﻿using System;
//using Wizard.Runtime;

namespace Wizard.Functions
{
    using Wizard.Runtime;
    public abstract class Function<ResultType> : IHasValue<ResultType>
    {
        private readonly string mName;
        private readonly FunctionType mType;
        protected bool mModified;
        private ResultType mValue;

        public Function(string name, FunctionType type)
        {
            mName = name;
            mType = type;
            mModified = true;
        }

        //public ValueType Type
        //{
        //    get { return mType; }
        //}

        public string Name
        {
            get { return mName; }
        }

        #region IHasValue<ResultType> Members

        //public ResultType Value(IRunContext context)
        //{
        //    if (mModified)
        //    {
        //        mValue = RecalcValue(context);
        //        mModified = false;
        //    }
        //    return mValue;
        //}

        public bool IsModified
        {
            get { return mModified; }
        }



        Type IHasValue.ValueType
        {
            get { return typeof(ResultType); }
        }


        #endregion

        public static Function<ResultType> Get(IHasValue value)
        {
            if (value is Function<ResultType>)
            {
                return (Function<ResultType>)value;
            }
            else return null;
        }

        protected abstract ResultType RecalcValue(IRunContext context);

        protected ResultType LastValue()
        {
            return mValue;
        }

        protected void SetModified(object sender, IValueChangedEventArgs e)
        {
            if (mModified == false)
            {
                mModified = true;
        //        if (ValueChanged != null) ValueChanged(sender, e);
            }
        }

        #region IHasValue<ResultType> Members

        bool IHasValue<ResultType>.IsModified
        {
            get { throw new NotImplementedException(); }
        }

        ResultType IHasValue<ResultType>.Value(IRunContext context)
        {
            throw new NotImplementedException();
        }

        #endregion

        #region IHasValue Members


        object IHasValue.GetValueObject(IRunContext context)
        {
            return null; // Value(context);
        }

        //public event ValueChangedEvent ValueChanged;

        event ValueChangedEvent IHasValue.ValueChanged
        {
            add { throw new NotImplementedException(); }
            remove { throw new NotImplementedException(); }
        }

        #endregion
    }
}